/*
 * Copyright (c) 2012 Sean Connelly
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

function byteList_create()
{
	var buf = new Buffer(0);
	return {
			_getBuf: function() {
					return buf;
				},

			size: function() {
					return buf.length;
				},
			clear: function() {
					buf = new Buffer(0);
					return this;
				},
			toString: function() {
					var out = '';
					for (var i = 0; i < buf.length; i++)
					{
						var str = buf[i].toString(16);
						out += (i == 0 ? '' : ' ') + (str.length < 2 ? '0' : '') + str;
					}
					return 'byteList{' + out + '}';
				},

			pushCopy: function() {
					var b = [buf];
					var ln = buf.length;
					for (var i = 0; i < arguments.length; i++)
					{
						var bf = arguments[i]._getBuf();
						b.push(bf);
						ln += bf.length;
					}
					buf = Buffer.concat(b, ln);
					return this;
				},

			pushByte: function() {
					var b = new Buffer(arguments.length);
					for (var i = 0; i < arguments.length; i++)
						b[i] = arguments[i];
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushSbyte: function() {
					var b = new Buffer(arguments.length);
					for (var i = 0; i < arguments.length; i++)
						b[i] = arguments[i] < 0 ? 256 + arguments[i] : arguments[i];
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},

			pushUshortLE: function() {
					var b = new Buffer(arguments.length * 2);
					for (var i = 0; i < arguments.length; i++)
						b.writeUInt16LE(arguments[i], i * 2);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushUshortBE: function() {
					var b = new Buffer(arguments.length * 2);
					for (var i = 0; i < arguments.length; i++)
						b.writeUInt16BE(arguments[i], i * 2);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushShortLE: function() {
					var b = new Buffer(arguments.length * 2);
					for (var i = 0; i < arguments.length; i++)
						b.writeInt16LE(arguments[i], i * 2);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushShortBE: function() {
					var b = new Buffer(arguments.length * 2);
					for (var i = 0; i < arguments.length; i++)
						b.writeInt16BE(arguments[i], i * 2);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},

			pushUintLE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeUInt32LE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushUintBE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeUInt32BE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushIntLE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeInt32LE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushIntBE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeInt32BE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},

			// long values don't cleanly exist in JavaScript... so skipped, unfortunately

			pushSingleLE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeFloatLE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushSingleBE: function() {
					var b = new Buffer(arguments.length * 4);
					for (var i = 0; i < arguments.length; i++)
						b.writeFloatBE(arguments[i], i * 4);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},

			pushDoubleLE: function() {
					var b = new Buffer(arguments.length * 8);
					for (var i = 0; i < arguments.length; i++)
						b.writeDoubleLE(arguments[i], i * 8);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				},
			pushDoubleBE: function() {
					var b = new Buffer(arguments.length * 8);
					for (var i = 0; i < arguments.length; i++)
						b.writeDoubleBE(arguments[i], i * 8);
					buf = Buffer.concat([buf, b], buf.length + b.length);
					return this;
				}
		};
}

exports.create = byteList_create;
